package com.ir.stat.spark.rest;

import com.ir.stat.spark.bean.ResourceDirStat;
import com.ir.stat.spark.config.AuthToken;
import com.ir.stat.spark.service.ResourceStatService;
import com.ir.stat.spark.service.StatService;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Path("stat")
public class StatAction {

    @Autowired
    private StatService statService;

    @Autowired
    private ResourceStatService resourceStatService;


    @GET
    @Path("/result/{id}")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Map result(@PathParam("id") String id) {
        return statService.getTaskResult(id);
    }

    @POST
    @Path("/deploy")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Map deploy(Map task) {
        boolean success = statService.offerTask(task);
        Map ret = new HashMap();
        ret.put("success", success);
        return ret;
    }

    private void doFilter(ResourceDirStat rds, String[] excludes) {
        for (String prop : excludes) {
            try {
                BeanUtils.setProperty(rds, prop, null);
            } catch (Throwable e) {
            }
        }
        if (rds.getChildren() != null) {
            for (ResourceDirStat _rds : rds.getChildren()) {
                doFilter(_rds, excludes);
            }
        }
    }

    @AuthToken
    @GET
    @Path("/{resType}")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Response getStat(@PathParam("resType") String resType, @QueryParam("excludes") String excludes) {
        ResourceDirStat rds = resourceStatService.getStat(resType);
        if (rds != null) {
            if (excludes != null) {
                String[] arr = excludes.split(",");
                doFilter(rds, arr);
            }
            return Response.status(200).entity(rds).build();
        }
        return Response.status(404).build();
    }

    @AuthToken
    @GET
    @Path("/{resType}/{resId}")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Response getStat(@PathParam("resType") String resType, @PathParam("resId") String resId, @QueryParam("excludes") String excludes) {
        ResourceDirStat rds = resourceStatService.getStat(resType, resId);
        if (rds != null) {
            if (excludes != null) {
                String[] arr = excludes.split(",");
                doFilter(rds, arr);
            }
            return Response.status(200).entity(rds).build();
        }
        return Response.status(404).build();
    }

    @AuthToken
    @GET
    @Path("/{resType}/count")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Response doStat(@PathParam("resType") final String resType) {
        List<String> supports = Arrays.asList("datasets", "datasources", "files", "ext_datasets");
        if (!supports.contains(resType)) {
            return Response.status(501).entity("Not Implemented for " + resType).build();
        } else {
            new Thread(() -> {
                switch (resType) {
                    case "ext_datasets":
                        resourceStatService.updateExtDataset();
                        break;
                    case "datasets":
                        resourceStatService.updateDataset();
                        break;
                    case "datasources":
                        resourceStatService.updateDatesource();
                        break;
                    case "files":
                        resourceStatService.updateFile();
                        break;
                }
            }).start();
            return Response.status(200).build();
        }
    }
}
